#ifndef __BUFFER_HPP__
#define __BUFFER_HPP__

#include <cstddef>
#include <cassert>
#include <vector>
namespace MyLog
{
    //没有超过阈值时每次容量成倍增长
    //超过阈值后容量每次线性增长
    #define DEFAULT_BUFFER_SIZE  (1*1024*1024)
    #define THRESOLD_BUFFER_SIZE (8*1024*1024)
    #define LINEAR_INCREMENT     (1*1024*1024)
    class Buffer
    {
    public:
        Buffer()
        {
            _buffer.resize(DEFAULT_BUFFER_SIZE);
            _writer_index=_reader_index=0;
        }
        void push(const char *data,std::size_t len)
        {
            // assert(len <= writeAbleSize());
            // 将数据放入缓冲区内
            // 如果写入数据超过缓冲区大小，处理方式1.扩容，2.阻塞
            // if(len > _buffer.size())return false;
            ensureEnoughSpace(len);//确保有足够空间写入
            std::copy(data,data+len,&_buffer[_writer_index]);//将指数拷贝至可写位置
            moveWriter(len);
        }
        // 返回可读位置
        const char *begin()
        {
            return &_buffer[_reader_index];
        }
        // 移动可读位置的指针
        void moveReader(std::size_t len)
        {
            assert(len<_buffer.size());
            _reader_index+=len;
        }
        // 重置可读位置和可写位置
        void reset()
        {
            _writer_index=0;
            _reader_index=0;
        }
        // 交换两个缓冲区，不交换缓冲区内部原有的数据
        void swap(Buffer &buffer)
        {
            _buffer.swap(buffer._buffer);
            std::swap(_writer_index,buffer._writer_index);
            std::swap(_reader_index,buffer._reader_index);
        }
        bool empty()
        {
            return _writer_index==_reader_index;
        }
        // 可写空间大小
        std::size_t writeAbleSize()
        {
            return _buffer.size()-_writer_index;
        }
        // 可读空间大小
        std::size_t readAbleSize()
        {
            return _writer_index-_reader_index;
        }
        // 确保缓冲区空间足够
        void ensureEnoughSpace(size_t len) 
        {
            // // 判断剩余空间是否足够
            // if (_buffer.size() - _writer_index < len) {
            //     std::size_t new_size;
            //     if (_buffer.size() < THRESOLD_BUFFER_SIZE) {
            //         new_size = std::max(_buffer.size() * 2, _writer_index + len);
            //     } else {
            //         new_size = _buffer.size() + LINEAR_INCREMENT + len;
            //     }
            //     _buffer.resize(new_size);
            // }
            if(len<=writeAbleSize())return;
            std::size_t new_size=0;
            if(_buffer.size() < THRESOLD_BUFFER_SIZE)
                new_size=_buffer.size()*2+len;
            else 
                new_size=_buffer.size()+LINEAR_INCREMENT+len;
            _buffer.resize(new_size);
        }
    protected:
        // 移动可读指针
        void moveWriter(std::size_t len)
        {
            assert(len<_buffer.size());
            _writer_index+=len;
        }
        
    private:
        std::size_t _writer_index;//可写数据的起始位置
        std::size_t _reader_index;//可读数据的起始位置
        std::vector<char> _buffer;//缓冲区
    };
}

#endif